package iscript.coreFramework.animation 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.utils.Timer;
	import iscript.coreFramework.interfaces.IDisposable;
	import iscript.coreFramework.layout.AlignLayout;
	import iscript.coreFramework.util.VectorHelper;

	public class BitmapPlayer extends Bitmap implements IAnimation,IDisposable 
	{
		
		public function BitmapPlayer(data:Vector.<BitmapData>) 
		{			
 			_bitmapdatas = data;
			_loop = true;
			_animationType = AnimationType.EnterFrame;
			this.addEventListener(Event.ADDED_TO_STAGE, _addToStageLogic)
			this.addEventListener(Event.REMOVED_FROM_STAGE, _removeFromStageLogic);
		}
		
        /***************************************************************************************/
		//static private var _bitmapPlayerList_All:Vector.<BitmapPlayer> = new Vector.<BitmapPlayer>();
		//static private var _bitmapPlayerList_Mouse:Vector.<BitmapPlayer> = new Vector.<BitmapPlayer>();
		//static private var _isRegisterMouseEvent:Boolean;
        /***************************************************************************************/
		
        public function get stageDepth():int {
			 if (_stage == null) return -1;
			 var  obj:DisplayObject = this;
			 var  depth:int = 0;
			  while (!(obj.parent is Stage)) { 
				  obj = obj.parent;
				  depth++;
				  }
			  return depth;
			}
		 
		public function get parentDepth():int {  
			 if (_stage == null) return -1;
			 return this.parent.getChildIndex(this);
			}	
			
			
		private var _stage:Stage;
		private var _pause:Boolean;
		private var _bitmapPlayerTimer:Timer;
		private var _bitmapdatas:Vector.<BitmapData> = new Vector.<BitmapData>();
		
		private var _animationType:String;
		public function get animationType():String { return _animationType; }
		public function set animationType(value:String):void { _animationType = value;}
		private var _mouseEnable:Boolean;
		public function get mouseEnable():Boolean { return _mouseEnable; }
		public function set mouseEnable(value:Boolean):void {_mouseEnable = value;}
							
		private var _fps:int=30;
		public function get fps():int { return _fps; }
		public function set fps(value:int):void { 
								_fps=(value > -1) ? value : 30;
								if(_bitmapPlayerTimer!=null){
								  _bitmapPlayerTimer.delay = 1000 / _fps;
								}
							}
		
		private var _loop:Boolean;
		public function get loop():Boolean { return _loop; }
		public function set loop(value:Boolean):void { _loop = value; }
		
		public function get TotalFrame():int { return _bitmapdatas.length; }
		
		private var _currentFrame:int = 0;
		public function get currentFrame():int { return _currentFrame; }
		public function set currentFrame(value:int):void { 
			 if (value < 0) _currentFrame = 0;
			 if (value > _bitmapdatas.length)_currentFrame = _bitmapdatas.length-1;
			}		  
		 
		private var _offsetX:Number=0;		
		private var _offsetY:Number=0;
		public function get offsetX():Number 
		{return _offsetX;}
		public function set offsetX(value:Number):void 
		{_offsetX = value; _setAlignLogic(); }
		public function get offsetY():Number 
		{return _offsetY;}
		public function set offsetY(value:Number):void 
		{_offsetY = value; _setAlignLogic(); }
		
		private  var _align:String=AlignLayout.TL;		
		public function set align(value:String):void { _align = value; _setAlignLogic();}		
		public function get align():String{return _align}
		
		public function Play():void {
			   this.bitmapData = _bitmapdatas[_currentFrame];
			   if(_bitmapdatas.length>1){			   
				   if(_animationType== AnimationType.EnterFrame)
				   this.addEventListener(Event.ENTER_FRAME, _onFrameLoopLogic);
				   if (_animationType == AnimationType.TIME) {
					   _bitmapPlayerTimer = new Timer(1000/_fps,_bitmapdatas.length);
					   _bitmapPlayerTimer.addEventListener(TimerEvent.TIMER,_timerLoopLogic)
					   _bitmapPlayerTimer.start(); 
					   }
				}
			}
			
		public function Pause():void {
               _pause = !_pause;
			   if (_pause && _bitmapPlayerTimer != null) {
				   _bitmapPlayerTimer.stop();
				   }
			   if (!_pause && _bitmapPlayerTimer != null) {
				   _bitmapPlayerTimer.start();
				   }
			}
			
		public function Stop():void {
			   this.removeEventListener(Event.ENTER_FRAME, _onFrameLoopLogic);	
			   if(_bitmapPlayerTimer!=null)_bitmapPlayerTimer.stop();
			}
			
		private function _addToStageLogic(e:Event):void {
			removeEventListener(Event.ADDED_TO_STAGE, _addToStageLogic);
			_stage = this.stage;			
			/*_bitmapPlayerList_All.push(this);  //ADD BitmapPlayer To List			
			if(!_isRegisterMouseEvent){
			  _stage.addEventListener(MouseEvent.CLICK, _stageCLICKLogic)
			  //_stage.addEventListener(MouseEvent.MOUSE_OVER, _stageCLICKLogic)
			  //_stage.addEventListener(MouseEvent.MOUSE_OUT, _stageCLICKLogic)
			  _isRegisterMouseEvent = true;
			}*/
		}
		
		private function _removeFromStageLogic(e:Event):void{
			removeEventListener(Event.REMOVED_FROM_STAGE, _removeFromStageLogic);
			/*for (var i:int = 0; i <_bitmapPlayerList_All.length; i++) 
				{
					if (_bitmapPlayerList_All[i] === this) {
						_bitmapPlayerList_All.splice(i, 1);  //Remove BitmapPlayer To List
						}
				}*/
			dispose();
		}
		
/*		private function _stageCLICKLogic(e:MouseEvent):void {	
			_bitmapPlayerList_Mouse = new Vector.<BitmapPlayer>();			
			for (var i:int = 0; i < _bitmapPlayerList_All.length; i++) 
			{
				if (!_bitmapPlayerList_All[i].mouseEnable || _bitmapPlayerList_All[i].alpha <= 0 || 
				    !_bitmapPlayerList_All[i].visible) continue;
				var _p:Point = _bitmapPlayerList_All[i].parent.localToGlobal(new Point(_bitmapPlayerList_All[i].x, _bitmapPlayerList_All[i].y));	
				if (_bitmapPlayerList_All[i].bitmapData.hitTest(_p, 255, new Point(_stage.mouseX, _stage.mouseY))) {
					_bitmapPlayerList_Mouse.push(_bitmapPlayerList_All[i]);
					} 
			}
			 var _targetBitmapPlayer:BitmapPlayer  = _getTargetFormDepth();
			 if (_targetBitmapPlayer != null)
			 _targetBitmapPlayer.dispatchEvent(new MouseEvent(BitmapPlayerEvent.MouseCLICK));
		}

		private function _getTargetFormDepth():BitmapPlayer {
				_bitmapPlayerList_Mouse.sort(VectorHelper.autoSortData("stageDepth"));											  
				if (_bitmapPlayerList_Mouse.length > 0) {
					var _clone:Vector.<BitmapPlayer> = new Vector.<BitmapPlayer>();
					var _stageDepth:int = _bitmapPlayerList_Mouse[0].stageDepth;
					for (var k:int = 0; k < _bitmapPlayerList_Mouse.length; k++) 
					{
						if (_bitmapPlayerList_Mouse[k].stageDepth == _stageDepth) {
							_clone.push(_bitmapPlayerList_Mouse[k]);
							}
					} 
					_clone.sort(VectorHelper.autoSortData("parentDepth"));	
					_clone.reverse();
				    return _clone[0];
				}
				return null;
			}
*/		
		private function _onFrameLoopLogic(e:Event):void {			 
			   this.bitmapData = _bitmapdatas[_currentFrame];
			   if (_pause) return;
			   _currentFrame++;
			   if (_currentFrame > _bitmapdatas.length - 1) {
				   _currentFrame = 0;
			     if(!_loop)this.Stop();
			   }
			}
			
		private function _timerLoopLogic(e:TimerEvent):void {		
			this.bitmapData = _bitmapdatas[_currentFrame];
			 _currentFrame++;
		     if (_currentFrame > _bitmapdatas.length - 1) {
				 _currentFrame = 0;
			      if (_loop) {
					   _bitmapPlayerTimer.reset();
					   _bitmapPlayerTimer.start();
					  }else {
						_bitmapPlayerTimer.stop();  
					  }
			   }
		}
		 
		private function _setAlignLogic():void{
			  switch (_align) 
				{
					case AlignLayout.TL:
						this.x = 0;
						this.y=0
						break;
					
					case AlignLayout.TC: 
						this.x = this.width/2*-1;
						this.y=0
						break;
					
					case AlignLayout.TR: 
						this.x = this.width*-1;
						this.y=0
						break;
					
	 
					case AlignLayout.CL: 
						this.x = 0;;
						this.y=this.height/2*-1;
						break;		 
					
					case AlignLayout.CC:
						this.x = this.width/2*-1;
						this.y=this.height/2*-1;
						break;
	 
					case AlignLayout.CR:
						this.x = this.width*-1;;
						this.y=this.height/2*-1;
						break;
					
						
					case AlignLayout.BL: 
						this.x = 0 ;
						this.y = this.height*-1;
						break;
					
					case AlignLayout.BC: 
						this.x = this.width/2*-1;
						this.y = this.height*-1;
						break;
					
					case AlignLayout.BR: 
						this.x = this.width*-1;
						this.y = this.height*-1;					
						break;
				}
	          this.x= this.x+offsetX
			  this.y= this.y+offsetY			 
			}
         
		public function dispose():void {
			this.Stop()
			this.bitmapData = null;
			if (_bitmapPlayerTimer != null) {
				_bitmapPlayerTimer.stop(); };
			}
			
	}
	

}